package org.hibernate.dao.impl;

import java.util.ArrayList;
import java.util.List;

import org.apache.log4j.Logger;
import org.compass.gps.device.hibernate.dep.AbstractHibernateGpsDevice.HibernateSessionWrapper;
import org.hibernate.Hibernate;
import org.hibernate.Query;
import org.hibernate.SQLQuery;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.dao.IBaseDao;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;

/**
 * 
 * @项目名称:cyj_trainer
 * @类名称:BaseDao
 * @类描述:统一的数据访问层实现类;
 * @创建人:苗有虎
 * @创建时间:Sep 18, 201010:07:12 AM
 * @修改人:Administrator
 * @修改时间:Sep 18, 201010:07:12 AM
 * @修改备注:
 * @version
 */
@SuppressWarnings("unchecked")
public class BaseDao extends HibernateDaoSupport implements IBaseDao {
	static Logger logger = Logger.getLogger(BaseDao.class.getName());

	public int countAll(String clazz) {
		Session session = null;
		Transaction tx = null;
		try {
			session = this.getAppSession();
			tx = session.beginTransaction();
			String hql = "select count(*) from " + clazz + " as a";
			Query query = session.createQuery(hql);
			query.setMaxResults(1);
			int result = Integer.parseInt(query.uniqueResult().toString());
			tx.commit();
			return result;
		} catch (Exception e) {
			if (tx != null && tx.isActive() && !tx.wasRolledBack()) {
				tx.rollback();
			}
			logger.error(e.getMessage(), e);
		} finally {
			if (tx != null && tx.isActive() && !tx.wasCommitted()
					&& !tx.wasRolledBack()) {
				tx.commit();
			}
			tx = null;
		}
		return 0;
	}

	public int countQuery(String hql) {
		Session session = null;
		Transaction tx = null;
		try {
			session = this.getAppSession();
			tx = session.beginTransaction();

			Query query = session.createQuery(hql);
			query.setMaxResults(1);
			Object result = query.uniqueResult();
			int countResult = result != null ? Integer.parseInt(result
					.toString()) : 0;
			tx.commit();
			return countResult;
		} catch (Exception e) {
			if (tx != null && tx.isActive() && !tx.wasRolledBack()) {
				tx.rollback();
			}
			logger.error(e.getMessage(), e);
		} finally {
			if (tx != null && tx.isActive() && !tx.wasCommitted()
					&& !tx.wasRolledBack()) {
				tx.commit();
			}
			tx = null;
		}
		return 0;
	}

	public int countSqlQuery(String sql) {
		Session session = null;
		Transaction tx = null;
		try {
			session = this.getAppSession();
			tx = session.beginTransaction();

			SQLQuery query = session.createSQLQuery(sql);
			query.setMaxResults(1);
			Object result = query.uniqueResult();
			int countResult = result != null ? Integer.parseInt(result
					.toString()) : 0;
			tx.commit();
			return countResult;
		} catch (Exception e) {
			if (tx != null && tx.isActive() && !tx.wasRolledBack()) {
				tx.rollback();
			}
			logger.error(e.getMessage(), e);
		} finally {
			if (tx != null && tx.isActive() && !tx.wasCommitted()
					&& !tx.wasRolledBack()) {
				tx.commit();
			}
			tx = null;
		}
		return 0;
	}

	public List listAll(String clazz, int pageNo, int pageSize) {
		Session session = null;
		Transaction tx = null;
		String hql = "from " + clazz + " as a";
		try {
			session = this.getAppSession();
			tx = session.beginTransaction();

			Query query = session.createQuery(hql);
			query.setMaxResults(pageSize);
			query.setFirstResult((pageNo - 1) * pageSize);
			List result = query.list();
			if (!Hibernate.isInitialized(result))
				Hibernate.initialize(result);
			tx.commit();
			return result;
		} catch (Exception e) {
			if (tx != null && tx.isActive() && !tx.wasRolledBack()) {
				tx.rollback();
			}
			logger.error(e.getMessage(), e);
		} finally {
			if (tx != null && tx.isActive() && !tx.wasCommitted()
					&& !tx.wasRolledBack()) {
				tx.commit();
			}
			tx = null;
		}
		return null;
	}

	public Object loadById(Class<?> clazz, int id) {
		Session session = null;
		Transaction tx = null;
		try {
			session = this.getAppSession();
			tx = session.beginTransaction();

			Object obj = session.get(clazz, id);
			tx.commit();
			return obj;
		} catch (Exception e) {
			if (tx != null && tx.isActive() && !tx.wasRolledBack()) {
				tx.rollback();
			}
			logger.error(e.getMessage(), e);
		} finally {
			if (tx != null && tx.isActive() && !tx.wasCommitted()
					&& !tx.wasRolledBack()) {
				tx.commit();
			}
			tx = null;
		}
		return null;
	}

	public Object loadByHql(String hql) {
		Session session = null;
		Transaction tx = null;
		Object obj = null;
		try {
			session = this.getAppSession();
			tx = session.beginTransaction();

			Query query = session.createQuery(hql);
			List list = query.list();
			if (list.size() > 0)
				obj = list.get(0);
			tx.commit();
			return obj;
		} catch (Exception e) {
			if (tx != null && tx.isActive() && !tx.wasRolledBack()) {
				tx.rollback();
			}
			logger.error(e.getMessage(), e);
		} finally {
			if (tx != null && tx.isActive() && !tx.wasCommitted()
					&& !tx.wasRolledBack()) {
				tx.commit();
			}
			tx = null;
		}
		return null;
	}

	public List query(String hql, int pageNo, int pageSize) {
		Session session = null;
		Transaction tx = null;
		try {
			session = this.getAppSession();
			tx = session.beginTransaction();

			Query query = session.createQuery(hql);
			query.setMaxResults(pageSize);
			query.setFirstResult((pageNo - 1) * pageSize);
			List result = query.list();
			if (!Hibernate.isInitialized(result))
				Hibernate.initialize(result);
			tx.commit();
			return result;
		} catch (Exception e) {
			if (tx != null && tx.isActive() && !tx.wasRolledBack()) {
				tx.rollback();
			}
			logger.error(e.getMessage(), e);
		} finally {
			if (tx != null && tx.isActive() && !tx.wasCommitted()
					&& !tx.wasRolledBack()) {
				tx.commit();
			}
			tx = null;
		}
		return null;
	}

	public List query(String hql) {
		Session session = null;
		Transaction tx = null;
		try {
			session = this.getAppSession();
			tx = session.beginTransaction();

			Query query = session.createQuery(hql);
			List obj = query.list();
			tx.commit();
			return obj;
		} catch (Exception e) {
			if (tx != null && tx.isActive() && !tx.wasRolledBack()) {
				tx.rollback();
			}
			logger.error(e.getMessage(), e);
		} finally {
			if (tx != null && tx.isActive() && !tx.wasCommitted()
					&& !tx.wasRolledBack()) {
				tx.commit();
			}
			tx = null;
		}
		return null;
	}

	public List query(String hql, boolean cache) {
		Session session = null;
		Transaction tx = null;
		try {
			session = this.getAppSession();
			tx = session.beginTransaction();

			Query query = session.createQuery(hql);
			query.setCacheable(cache);
			if (cache) {
				query.setCacheRegion("Forever");
			}
			List obj = query.list();
			tx.commit();
			return obj;
		} catch (Exception e) {
			if (tx != null && tx.isActive() && !tx.wasRolledBack()) {
				tx.rollback();
			}
			logger.error(e.getMessage(), e);
		} finally {
			if (tx != null && tx.isActive() && !tx.wasCommitted()
					&& !tx.wasRolledBack()) {
				tx.commit();
			}
			tx = null;
		}
		return null;
	}

	public void saveOrUpdate(Object obj) {
		Session session = null;
		Transaction tx = null;
		try {
			session = getAppSession();
			tx = session.beginTransaction();
			session.saveOrUpdate(obj);
			tx.commit();
		} catch (Exception e) {
			if (tx != null && tx.isActive() && !tx.wasRolledBack()) {
				tx.rollback();
			}
			logger.error(e.getMessage(), e);
		} finally {
			if (tx != null && tx.isActive() && !tx.wasCommitted()
					&& !tx.wasRolledBack()) {
				tx.commit();
			}
			tx = null;
		}
	}

	public int update(String hql) {
		Session session = null;
		Transaction tx = null;
		try {
			session = getAppSession();
			tx = session.beginTransaction();
			Query query = session.createQuery(hql);
			int result = query.executeUpdate();
			tx.commit();
			return result;
		} catch (Exception e) {
			if (tx != null && tx.isActive() && !tx.wasRolledBack()) {
				tx.rollback();
			}
			logger.error(e.getMessage(), e);
		} finally {
			if (tx != null && tx.isActive() && !tx.wasCommitted()
					&& !tx.wasRolledBack()) {
				tx.commit();
			}
			tx = null;
		}
		return 0;
	}

	public List getPageBySql(Class cla, String sql, int pageNo, int pageSize) {
		Session session = null;
		Transaction tx = null;
		try {
			session = this.getAppSession();
			tx = session.beginTransaction();
			List result = session.createSQLQuery(sql).addEntity(cla)
					.setFirstResult((pageNo - 1) * pageSize).setMaxResults(
							pageSize).list();

			tx.commit();
			return result;
		} catch (Exception e) {
			if (tx != null && tx.isActive() && !tx.wasRolledBack()) {
				tx.rollback();
			}
			logger.error(e.getMessage(), e);
		} finally {
			if (tx != null && tx.isActive() && !tx.wasCommitted()
					&& !tx.wasRolledBack()) {
				tx.commit();
			}
			tx = null;
		}
		return null;
	}

	public List getObjectBySQL(Class entity, String sql) {
		Session session = null;
		Transaction tx = null;
		try {
			session = this.getAppSession();
			tx = session.beginTransaction();
			SQLQuery query = session.createSQLQuery(sql);
			query.addEntity(entity);

			tx.commit();
			return query.list();
		} catch (Exception e) {
			if (tx != null && tx.isActive() && !tx.wasRolledBack()) {
				tx.rollback();
			}
			logger.error(e.getMessage(), e);
		} finally {
			if (tx != null && tx.isActive() && !tx.wasCommitted()
					&& !tx.wasRolledBack()) {
				tx.commit();
			}
			tx = null;
		}
		return null;
	}

	public boolean delObjectBySQL(Class entity, String sql) {
		Session session = null;
		Transaction tx = null;
		try {
			session = getAppSession();
			tx = session.beginTransaction();
			SQLQuery query = session.createSQLQuery(sql);
			query.addEntity(entity);
			int result = query.executeUpdate();
			tx.commit();
			return result > 0 ? true : false;
		} catch (Exception e) {
			if (tx != null && tx.isActive() && !tx.wasRolledBack()) {
				tx.rollback();
			}
			logger.error(e.getMessage(), e);
		} finally {
			if (tx != null && tx.isActive() && !tx.wasCommitted()
					&& !tx.wasRolledBack()) {
				tx.commit();
			}
			tx = null;
		}
		return false;
	}

	/**
	 * ***************************11.21号
	 * 底层DAO数据优化,添加运行事务************************************************
	 */

	public Object loadObjClearSessionFirst(Class<?> clazz, int id) {
		Session session = null;
		Transaction tx = null;
		try {
			session = this.getAppSession();
			tx = session.beginTransaction();
			session.clear();
			session.flush();
			Object obj = session.get(clazz, id);
			tx.commit();
			return obj;
		} catch (Exception e) {
			if (tx != null && tx.isActive() && !tx.wasRolledBack()) {
				tx.rollback();
			}
			logger.error(e.getMessage(), e);
		} finally {
			if (tx != null && tx.isActive() && !tx.wasCommitted()
					&& !tx.wasRolledBack()) {
				tx.commit();
			}
			tx = null;
		}
		return null;
	}

	public Object load(Class<?> clazz, int id) {
		Session session = null;
		Transaction tx = null;
		try {
			session = this.getAppSession();
			tx = session.beginTransaction();
			Object obj = session.get(clazz, id);
			tx.commit();
			return obj;
		} catch (Exception e) {
			if (tx != null && tx.isActive() && !tx.wasRolledBack()) {
				tx.rollback();
			}
			logger.error(e.getMessage(), e);
		} finally {
			if (tx != null && tx.isActive() && !tx.wasCommitted()
					&& !tx.wasRolledBack()) {
				tx.commit();
			}
			tx = null;
		}
		return null;
	}

	public Object save(Object obj) {
		Session session = null;
		Transaction tx = null;
		try {
			session = getAppSession();
			tx = session.beginTransaction();
			session.save(obj);
			tx.commit();
		} catch (Exception e) {
			if (tx != null && tx.isActive() && !tx.wasRolledBack()) {
				tx.rollback();
			}
			logger.error(e.getMessage(), e);
		} finally {
			if (tx != null && tx.isActive() && !tx.wasCommitted()
					&& !tx.wasRolledBack()) {
				tx.commit();
			}
			tx = null;
		}
		return obj;
	}

	public Object updateObject(Object obj) {
		Session session = null;
		Transaction tx = null;
		try {
			session = getAppSession();
			tx = session.beginTransaction();
			session.update(obj);
			tx.commit();
		} catch (Exception e) {
			if (tx != null && tx.isActive() && !tx.wasRolledBack()) {
				tx.rollback();
			}
			logger.error(e.getMessage(), e);
		} finally {
			if (tx != null && tx.isActive() && !tx.wasCommitted()
					&& !tx.wasRolledBack()) {
				tx.commit();
			}
			tx = null;
		}
		return obj;
	}

	public boolean saveList(List<?> list) {
		if (list == null || list.size() == 0) {
			return true;
		}
		Session session = null;
		Transaction tx = null;
		try {
			session = getAppSession();
			tx = session.beginTransaction();
			for (Object obj : list) {
				session.save(obj);
			}
			tx.commit();
			return true;
		} catch (Exception e) {
			if (tx != null && tx.isActive() && !tx.wasRolledBack()) {
				tx.rollback();
			}
			logger.error(e.getMessage(), e);
		} finally {
			if (tx != null && tx.isActive() && !tx.wasCommitted()
					&& !tx.wasRolledBack()) {
				tx.commit();
			}
			tx = null;
		}
		return false;
	}

	public boolean deleteObj(Object obj) {
		Session session = null;
		Transaction tx = null;
		try {
			session = getAppSession();
			tx = session.beginTransaction();
			session.delete(obj);
			tx.commit();
			return true;
		} catch (Exception e) {
			if (tx != null && tx.isActive() && !tx.wasRolledBack()) {
				tx.rollback();
			}
			logger.error(e.getMessage(), e);
		} finally {
			if (tx != null && tx.isActive() && !tx.wasCommitted()
					&& !tx.wasRolledBack()) {
				tx.commit();
			}
			tx = null;
		}
		return false;
	}

	public boolean updateByHqlList(List<String> list) {
		if (list == null || list.size() == 0) {
			return true;
		}
		Session session = null;
		Transaction tx = null;
		try {
			session = getAppSession();
			tx = session.beginTransaction();
			for (String hql : list) {
				Query q = session.createQuery(hql);
				q.executeUpdate();
			}
			tx.commit();
			return true;
		} catch (Exception e) {
			if (tx != null && tx.isActive() && !tx.wasRolledBack()) {
				tx.rollback();
			}
			logger.error(e.getMessage(), e);
		} finally {
			if (tx != null && tx.isActive() && !tx.wasCommitted()
					&& !tx.wasRolledBack()) {
				tx.commit();
			}
			tx = null;
		}
		return false;
	}

	public List<?> getTopList(String hql, int size) {
		Session session = null;
		Transaction tx = null;
		try {
			session = getAppSession();
			tx = session.beginTransaction();
			Query q = session.createQuery(hql);
			q.setMaxResults(size);
			List<?> list = q.list();
			tx.commit();
			return list;
		} catch (Exception e) {
			if (tx != null && tx.isActive() && !tx.wasRolledBack()) {
				tx.rollback();
			}
			logger.error(e.getMessage(), e);
		} finally {
			if (tx != null && tx.isActive() && !tx.wasCommitted()
					&& !tx.wasRolledBack()) {
				tx.commit();
			}
			tx = null;
		}
		return new ArrayList<Object>();
	}

	/**
	 * 获取当前的SESSION对象;
	 * 
	 * @return
	 */
	public Session getAppSession() {
		return this.getSessionFactory().getCurrentSession();
	}
}
